package com.ainote.service.impl;

import com.ainote.service.NlpService;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;// 引入 PostConstruct
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit; // 引入 TimeUnit
import java.util.stream.Collectors;

/**
 * DeepSeek NLP 完整实现
 * 使用 DeepSeek API 进行文本摘要和关键点提取
 *
 * API文档: https://platform.deepseek.com/api-docs/
 */
@Service("deepSeekNlpService")
public class DeepSeekNlpService implements NlpService {

    @Value("${nlp.deepseek.api_key}")
    private String apiKey;

    @Value("${nlp.deepseek.api_url}")
    private String apiUrl;

    @Value("${nlp.deepseek.model}")
    private String model;

    // 【修改点 1：注入超时配置】
    // 注入配置，使用 60000ms 作为默认值，确保配置未找到时也有足够长的超时
    @Value("${nlp.deepseek.timeout}")
    private int deepseekTimeout; // 注入毫秒值

    // 【修改点 2：延迟初始化 OkHttpClient】
    // 移除默认初始化，改为 null，在 @PostConstruct 中配置
    private OkHttpClient httpClient;
    private final ObjectMapper mapper = new ObjectMapper();

    private static final String SYSTEM_PROMPT = "你是一个专业的文本分析助手。请对用户提供的文本进行以下分析：\n" +
            "1. 生成一个简洁准确的摘要（200字以内）\n" +
            "2. 提取3-5个最重要的关键点\n" +
            "请严格按照JSON格式返回结果，格式如下：\n" +
            "{\n" +
            "  \"summary\": \"文本摘要内容\",\n" +
            "  \"keyPoints\": [\"关键点1\", \"关键点2\", \"关键点3\"]\n" +
            "}";



    // 【修改点 3：初始化方法 - 应用超时配置】
    @PostConstruct
    public void init() {
        // 将毫秒转换为秒（OkHttpClient通常以秒为单位设置）
        long timeoutSeconds = (long) deepseekTimeout / 1000;

        // 使用配置的值初始化 OkHttpClient，延长超时时间
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(timeoutSeconds, TimeUnit.SECONDS) // 连接超时
                .readTimeout(timeoutSeconds, TimeUnit.SECONDS)    // 读取超时
                .writeTimeout(timeoutSeconds, TimeUnit.SECONDS)   // 写入超时
                .build();
    }

    // --- 【修改点 1】实现 NlpService 接口中 analyze(String transcript) 方法 ---
    /**
     * @Override NlpService.analyze(String transcript)
     * 接收转录文本，调用 NLP 服务提取摘要与关键信息。
     * 返回 Map<String, String>，其中 keyPoints 是一个用换行符分隔的字符串。
     */
    @Override
    public Map<String, String> analyze(String transcript) throws Exception {
        // 调用包含完整逻辑的 extractSummaryAndKeyPoints
        Map<String, Object> fullResult = extractSummaryAndKeyPoints(transcript);

        // 进行类型转换，以匹配 NoteController 对 Map<String, String> 的预期
        String summary = (String) fullResult.get("summary");

        // 将 List<String> 转换成 String，通常使用换行符或分号分隔
        @SuppressWarnings("unchecked")
        List<String> keyPointsList = (List<String>) fullResult.get("keyPoints");
        String keyPointsString = keyPointsList.stream()
                .collect(Collectors.joining("\n")); // 使用换行符分隔
        Map<String, String> result = new HashMap<>();
        result.put("summary", summary);
        result.put("keyPoints", keyPointsString);

        // 记录日志或使用 Map<String, String> 即可，不包含 usage
        return result;
    }


    // --- 【修改点 2】 extractSummaryAndKeyPoints 方法优化 (主逻辑) ---
    /**
     * @Override NlpService.extractSummaryAndKeyPoints(String text)
     * 基于全文提取摘要与关键点，返回完整的分析结果，包括使用量 (usage)。
     */
    @Override
    public Map<String, Object> extractSummaryAndKeyPoints(String text) throws Exception {
        if (text == null || text.trim().isEmpty()) {
            throw new IllegalArgumentException("输入文本不能为空");
        }

        if (apiKey == null || apiKey.isEmpty()) {
            throw new IllegalStateException("请在配置文件中设置 nlp.deepseek.api_key");
        }

        // 限制文本长度以避免不必要的开销或 API 限制
        if (text.length() > 20000) {
            throw new IllegalArgumentException("输入文本过长，请勿超过 20000 字符。");
        }

        // 构造请求消息
        Map<String, Object> message = new HashMap<>();
        message.put("role", "user");
        message.put("content", "请分析以下文本：\n" + text);

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", model);
        requestBody.put("messages", List.of(
                Map.of("role", "system", "content", SYSTEM_PROMPT),
                message
        ));
        requestBody.put("temperature", 0.3);
        requestBody.put("max_tokens", 2000);
        requestBody.put("response_format", Map.of("type", "json_object"));

        String jsonBody = mapper.writeValueAsString(requestBody);

        // 创建HTTP请求
        Request request = new Request.Builder()
                .url(apiUrl)
                .post(RequestBody.create(jsonBody, MediaType.parse("application/json")))
                .addHeader("Authorization", "Bearer " + apiKey)
                .addHeader("Content-Type", "application/json")
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            String responseBody = response.body().string();

            if (!response.isSuccessful()) {
                // 确保异常信息中包含API返回的错误细节
                String errorMessage = "DeepSeek API调用失败: HTTP " + response.code() + ", 响应: " + responseBody;
                try {
                    JsonNode errorNode = mapper.readTree(responseBody).path("error");
                    if (!errorNode.isMissingNode() && errorNode.has("message")) {
                        errorMessage = "DeepSeek API返回错误: " + errorNode.get("message").asText();
                    }
                } catch (IOException ignored) {
                    // 无法解析 JSON，使用原始 HTTP 错误
                }
                throw new RuntimeException(errorMessage);
            }

            JsonNode root = mapper.readTree(responseBody);

            // 检查API返回的顶层错误（通常在 !response.isSuccessful() 中已捕获）
            if (root.has("error")) {
                throw new RuntimeException("DeepSeek API返回错误: " + root.get("error").get("message").asText());
            }

            // 解析响应
            JsonNode choice = root.path("choices").path(0);
            if (choice.isMissingNode()) {
                throw new RuntimeException("DeepSeek API响应格式错误，缺少 'choices' 字段。");
            }

            JsonNode messageNode = choice.path("message");
            String content = messageNode.path("content").asText("");

            if (content.isEmpty()) {
                throw new RuntimeException("API返回的内容为空，无法进行解析。");
            }

            // 解析JSON响应
            JsonNode result = mapper.readTree(content);

            String summary = result.path("summary").asText("");
            JsonNode keyPointsNode = result.path("keyPoints");
            List<String> keyPoints = new ArrayList<>();

            if (keyPointsNode.isArray()) {
                for (JsonNode point : keyPointsNode) {
                    keyPoints.add(point.asText());
                }
            }

            // 验证结果
            if (summary.isEmpty()) {
                throw new RuntimeException("API返回的摘要为空");
            }

            if (keyPoints.isEmpty()) {
                // 即使 keyPoints 为空，如果摘要有效，可以只警告而不是抛出异常
                // 这里保持原逻辑：抛出异常
                throw new RuntimeException("API返回的关键点列表为空");
            }

            return Map.of(
                    "summary", summary,
                    "keyPoints", keyPoints,
                    "usage", Map.of(
                            "promptTokens", root.path("usage").path("prompt_tokens").asInt(0),
                            "completionTokens", root.path("usage").path("completion_tokens").asInt(0),
                            "totalTokens", root.path("usage").path("total_tokens").asInt(0)
                    )
            );

        } catch (IOException e) {
            // 捕获网络、IO、JSON解析等错误
            throw new RuntimeException("处理DeepSeek API连接或数据时发生错误: " + e.getMessage(), e);
        } catch (Exception e) {
            // 捕获 RuntimeException, IllegalArgumentException 等
            throw e;
        }
    }


    /**
     * 测试API连接
     */
    public boolean testConnection() throws Exception {
        if (apiKey == null || apiKey.isEmpty()) {
            return false;
        }

        try {
            Map<String, Object> testResult = extractSummaryAndKeyPoints("测试文本");
            return testResult != null && testResult.containsKey("summary");
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取模型信息
     */
    public Map<String, Object> getModelInfo() {
        return Map.of(
                "provider", "DeepSeek",
                "model", model,
                "apiUrl", apiUrl,
                "configured", apiKey != null && !apiKey.isEmpty()
        );
    }


    /**
     * 临时测试 DeepSeek 密匙和连接是否有效
     */
    public String testApiKey() {
        String testUrl = "https://api.deepseek.com/v1/chat/completions";
        ObjectMapper mapper = new ObjectMapper();

        try {
            // 构造一个简单的测试请求体
            String jsonPayload = String.format("""
                {
                    "model": "deepseek-chat",
                    "messages": [
                        {"role": "user", "content": "Hello, how are you?"}
                    ],
                    "max_tokens": 5
                }
                """);

            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                    .uri(URI.create(testUrl))
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Bearer " + apiKey) // 使用您的 API Key
                    .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                    .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

            // 检查 HTTP 状态码
            if (response.statusCode() == 200) {
                // 如果返回 200，说明密钥和连接基本没问题
                JsonNode root = mapper.readTree(response.body());
                String model = root.has("model") ? root.get("model").asText() : "N/A";
                return "SUCCESS: API Key有效。模型响应正常。状态码: 200。模型: " + model;
            } else {
                // 如果返回 401 (Unauthorized) 或其他错误，通常是密钥问题
                String errorBody = response.body();
                return "FAILURE: API Key或权限有问题。状态码: " + response.statusCode() + "。响应体: " + errorBody.substring(0, Math.min(errorBody.length(), 200)) + "...";
            }

        } catch (Exception e) {
            // 捕获网络连接或解析异常
            return "ERROR: 网络连接或代码执行异常。请检查网络和 DeepSeek URL。异常信息: " + e.getMessage();
        }
    }
}